package site.wenneng.dev.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import site.wenneng.dev.service.BaseService;
import site.wenneng.dev.objs.po.DevUserPO;
import site.wenneng.dev.objs.bo.TaskRemoteBO;
import site.wenneng.dev.objs.query.TaskRemoteQuery;
import site.wenneng.dev.service.SimpleBizService;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@AllArgsConstructor
public class TaskService extends BaseService {

    private SimpleBizService simpleBizService;
    private DevUserService userService;

    @SneakyThrows
    public List<TaskRemoteBO> queryTaskFromRemote(TaskRemoteQuery query) {
        String payload = processRequest("req/task.json.ftlh", query);
        Request request = new Request.Builder()
                .url("https://dev.hundsun.com/heppm/task/queryByConditionV4")
                .post(RequestBody.create(payload, MediaType.parse("application/json")))
                .build();
        ObjectMapper objectMapper = getObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(invoke(request));
        JsonNode codeNode = jsonNode.get("code");
        if (codeNode == null || !codeNode.textValue().equals("200")) {
            log.error("请求失败：{}", jsonNode.toPrettyString());
            return Collections.emptyList();
        }
        return objectMapper.readValue(jsonNode.get("data").get("items").traverse(), new TypeReference<List<TaskRemoteBO>>() {
        });
    }

    public List<TaskRemoteBO> queryByTaskNumbers(Collection<String> taskNumbers, String fromJira) {
        if (taskNumbers.size() == 0) {
            return Collections.emptyList();
        }
        TaskRemoteQuery query = TaskRemoteQuery.builder()
                .productList(simpleBizService.listAllProductIdList())
                .projectList(simpleBizService.listAllProjectIdList())
                .fromJira(fromJira)
                .taskNumberList(new ArrayList<>(taskNumbers)).build();
        return queryTaskFromRemote(query);
    }

    public List<TaskRemoteBO> queryByStoryNumber(List<String> storyNumberList) {
        if (CollectionUtils.isEmpty(storyNumberList)) {
            return Collections.emptyList();
        }
        return queryByStoryNumber(storyNumberList, null);
    }

    public List<TaskRemoteBO> queryUnFinishTaskByExpectDate(LocalDate start, LocalDate end) {
        TaskRemoteQuery query = TaskRemoteQuery.builder()
                .productList(simpleBizService.listAllProductIdList())
                .projectList(simpleBizService.listAllProjectIdList())
                .twoDimStatus("[[1,0],[1,4],[1,5],[1,6],[1,16],[1,8],[1,14],[1,19],[1,20],[1,13],[1,21],[1,18],[2,0],[2,1],[2,23]]")
                .assigneeIdList(userService.getAllAssigneeId())
                .expectStartTime(start.format(DateTimeFormatter.ISO_LOCAL_DATE) + " 00:00:00")
                .expectEndTime(end.format(DateTimeFormatter.ISO_LOCAL_DATE) + " 00:00:00")
                .build();
        return queryTaskFromRemote(query);
    }

    public List<TaskRemoteBO> queryByStoryNumber(List<String> storyNumberList, String versionList) {
        if (storyNumberList.size() == 0) {
            return Collections.emptyList();
        }
        TaskRemoteQuery query = TaskRemoteQuery.builder()
                .productList(simpleBizService.listAllProductIdList())
                .projectList(simpleBizService.listAllProjectIdList())
                .versionSearch(versionList)
                .storyNumberList(storyNumberList)
                .assigneeIdList(userService.getAllAssigneeId()).build();
        return queryTaskFromRemote(query);
    }

    public List<TaskRemoteBO> queryUnfinishedTask(List<DevUserPO> userList) {
        List<String> assigneeIdList = userList.stream().map(DevUserPO::getAssigneeId).collect(Collectors.toList());
        // 查询组内待完成任务
        TaskRemoteQuery taskRemoteQuery = new TaskRemoteQuery();
        taskRemoteQuery.setAssigneeIdList(assigneeIdList);
        taskRemoteQuery.setTwoDimStatus("[[1,0],[1,4],[1,5],[1,6],[1,16],[1,8],[1,14],[1,19],[1,13],[1,21],[1,17],[1,18],[2,0],[2,1],[2,22],[2,23]]");
        return queryTaskFromRemote(taskRemoteQuery);
    }

    public List<TaskRemoteBO> queryUnfinishedTaskContainUncheck(List<DevUserPO> userList) {
        List<String> assigneeIdList = userList.stream().map(DevUserPO::getAssigneeId).collect(Collectors.toList());
        // 查询组内待完成任务
        TaskRemoteQuery taskRemoteQuery = new TaskRemoteQuery();
        taskRemoteQuery.setAssigneeIdList(assigneeIdList);
        taskRemoteQuery.setTwoDimStatus("[[1,17],[1,0],[1,4],[1,5],[1,6],[1,16],[1,7],[1,14],[1,19],[1,21],[1,18],[2,0],[2,1],[2,22],[2,23]]");
        return queryTaskFromRemote(taskRemoteQuery);
    }


    @NotNull
    public Map<String, List<TaskRemoteBO>> getStoryTaskMap(List<TaskRemoteBO> taskRemoteBOList) {
        return getStoryTaskMap(taskRemoteBOList, true);
    }

    @NotNull
    public Map<String, List<TaskRemoteBO>> getStoryTaskMap(List<TaskRemoteBO> taskRemoteBOList, boolean multiStory) {
        Map<String, List<TaskRemoteBO>> taskMap = new HashMap<>();
        for (TaskRemoteBO taskRemoteBO : taskRemoteBOList) {
            String storyNumbers = taskRemoteBO.getStoryNumbers();
            if (StringUtils.isEmpty(storyNumbers)) {
                storyNumbers = "202401010000";
            }
            List<String> numberList = Arrays.stream(storyNumbers.split(","))
                    .filter(StringUtils::isNotBlank).sorted().collect(Collectors.toList());

            for (String storyNumber : numberList) {
                taskMap.computeIfAbsent(storyNumber, item -> new ArrayList<>()).add(taskRemoteBO);
                if (!multiStory) {
                    break;
                }
            }
        }
        return taskMap;
    }


}
